<template>
  <div v-if="readonly" class="itemNames">
    <span v-for="i in names" :key="i">{{ i }}</span>
  </div>
  <el-cascader
    v-else
    v-model="chioseKey"
    :options="treeItems"
    :placeholder="placeholder"
    :props="treeProps"
    :clearable="clearable"
    :disabled="disabled"
    style="min-width: 200px"
    class="el-input"
    @change="handleChange"
  />
</template>

<script>
import { getTrees, GetNames } from '@/api/base/treeDicItem'
export default {
  name: 'TreeDicItem',
  props: {
    clearable: {
      type: Boolean,
      default: true
    },
    placeholder: {
      type: String,
      default: '选择字典'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: null
    },
    readonly: {
      type: Boolean,
      default: false
    },
    isMultiple: {
      type: Boolean,
      default: false
    },
    parentId: {
      type: String,
      default: null
    },
    isChoiceEnd: {
      type: Boolean,
      default: true
    },
    dicId: {
      type: String,
      default: null
    },
    value: {
      default: null
    }
  },
  data() {
    return {
      treeItems: [],
      chioseKey: null,
      item: {},
      names: [],
      treeProps: {
        multiple: false,
        emitPath: false,
        checkStrictly: true,
        value: 'DicValue',
        label: 'DicText',
        children: 'Children'
      }
    }
  },
  watch: {
    dicId: {
      handler(val) {
        if (val != null) {
          this.reset()
        }
      },
      immediate: true
    },
    value: {
      handler(val) {
        this.chioseKey = val
        if (this.readonly && val) {
          this.reset()
        }
      },
      immediate: true
    }
  },
  methods: {
    reset() {
      if (this.readonly) {
        if (this.value == null) {
          this.names = []
          return
        } else if (this.isMultiple && this.value.length !== 0) {
          this.loadNames(this.value)
        } else if (this.isMultiple === false) {
          this.loadNames([this.value])
        } else {
          this.names = []
        }
      } else {
        this.loadTree()
      }
    },
    async loadTree() {
      const res = await getTrees(this.dicId, this.parentId)
      this.treeProps.checkStrictly = this.isChoiceEnd === false
      this.treeProps.multiple = this.isMultiple
      this.item = {}
      res.forEach((c) => {
        this.item[c.DicValue] = c
        this.format(c)
      })
      this.treeItems = res
      this.$emit('load', {
        source: res,
        items: this.item
      })
      if (this.value != null) {
        const vals = Array.isArray(this.value) ? this.value : [this.value]
        this.refreshLabel(vals)
      }
    },
    async loadNames(ids) {
      this.names = await GetNames(this.dicId, ids)
      this.$emit('update:label', this.names.join(','))
    },
    format(row) {
      if (row.Children) {
        if (row.Children.length === 0) {
          row.Children = null
        } else {
          row.Children.forEach((c) => {
            this.item[c.DicValue] = c
            this.format(c)
          })
        }
      }
    },
    formatText(vals) {
      if (vals.length === 1) {
        return this.item[vals[0]].DicText
      }
      let text = ''
      vals.forEach(c => {
        text = text + ',' + this.item[c].DicText
      })
      return text.substring(1)
    },
    refreshLabel(val) {
      const label = this.formatText(val)
      this.$emit('update:label', label)
    },
    handleChange(val) {
      const e = {
        isMultiple: this.isMultiple,
        value: null,
        item: null
      }
      if (this.isMultiple) {
        e.value = val
        e.item = val.map(c => this.item[c])
      } else if (val) {
        e.value = [val]
        e.item = [this.item[val]]
      } else {
        e.value = []
      }
      this.$emit('input', val)
      this.$emit('change', e)
      this.refreshLabel(e.value)
    }
  }
}
</script>

<style scoped>
.itemNames {
  display: inline-block;
  line-height: 20px;
  min-width: 100px
}
.itemNames span{
  padding: 5px;
}
</style>
